package com.gec.system.filter;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gec.system.custom.CustomUser;
import com.gec.system.exception.MyCustomException;
import com.gec.system.sevice.SysLoginLogService;
import com.gec.system.util.JwtHelper;
import com.gec.system.util.ResponseUtil;
import com.gec.system.util.Result;
import com.gec.system.util.ResultCodeEnum;
import com.gec.system.utils.IPUtil;
import com.gec.system.vo.SysLoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {
    private RedisTemplate redisTemplate;
    private SysLoginLogService loginLogService;

    public TokenLoginFilter(AuthenticationManager authenticationManager,
                            RedisTemplate redisTemplate,SysLoginLogService loginLogService

    ) {
        this.setAuthenticationManager(authenticationManager);

        this.setPostOnly(false);
        this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/system/index/login","POST"));
        this.redisTemplate=redisTemplate;
        this.loginLogService= loginLogService;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            SysLoginVo loginVo = new ObjectMapper().readValue(request.getInputStream(), SysLoginVo.class);
            Authentication token = new UsernamePasswordAuthenticationToken(loginVo.getUsername(), loginVo.getPassword());
            return this.getAuthenticationManager().authenticate(token);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        CustomUser principal = (CustomUser) authResult.getPrincipal();
        String token = JwtHelper.createToken(principal.getSysUser().getId()+"", principal.getSysUser().getUsername());
        redisTemplate.opsForValue().set(principal.getUsername(), JSON.toJSONString(principal.getAuthorities()));
        loginLogService.recordLoginLog(principal.getUsername(),1, IPUtil.getIpAddress(request),"登陆成功");
        HashMap<Object, Object> map = new HashMap<>();
        map.put("token",token);
        ResponseUtil.out(response, Result.ok(map));
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        if(failed instanceof RuntimeException){
            ResponseUtil.out(response,Result.build(null,204,failed.getMessage()));
        }else {
            ResponseUtil.out(response,Result.build(null, ResultCodeEnum.LOGIN_MOBLE_ERROR));
        }

    }
}
